#include "VAsmWidget.h"
#include "VFunctions.h"
#include "VGlobal.h"

#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonDocument>
#include <QDebug>

VAsmWidget::VAsmWidget(QWidget *parent):
    VScintillaBase(parent)
{
    this->setLexer(&_lexer);
    init_setting();
    init_color();
    init_option();
	init_connect(); 
    this->setMarginType(QsciScintilla::SC_MARGIN_SYMBOL, QsciScintilla::MarginType::SymbolMargin);
//	this->setMarkerBackgroundColor(0xe6e7e8, QsciScintilla::SC_MARGIN_SYMBOL);


    this->SendScintilla(QsciScintilla::SC_MARGIN_SYMBOL, QsciScintilla::SC_CURSORWAIT);
                    //                        VFunctions::RGB2BGR(_style_map.value("行号").fore));

//	for(int i=0; i<100; i++){
//		this->setMarginBackgroundColor(i, QColor(Qt::red));
//		this->SendScintilla(QsciScintilla::SCI_SETMARGINBACKN, i, 0xe6e7e8);
//	}
//    this->SendScintilla(QsciScintilla::SCI_SETMARGINBACKN, QsciScintilla::SC_MARGIN_SYMBOL ,0xe6e7e8);
    
//    this->SendScintilla(QsciScintilla::SCI_STYLESETBACK, QsciScintilla::STYLE_DEFAULT,
//                        0xe6e7e8);
//    this->SendScintilla(QsciScintilla::SCI_STYLESETFORE, QsciScintilla::STYLE_LINENUMBER,
//                        VFunctions::RGB2BGR(_style_map.value("行号").fore));


    this->setMarginWidth(QsciScintilla::SC_MARGIN_SYMBOL, 16);
    this->setMarginWidth(QsciScintilla::SC_MARGIN_NUMBER, 0);
    this->setMarginMarkerMask(QsciScintilla::SC_MARGIN_SYMBOL, 0x0F);
    this->setMarginMarkerMask(QsciScintilla::SC_MARGIN_NUMBER, 0x0);


    this->markerDefine(QImage(VGlobal::icon_path.value("arror")), 3);
    this->markerDefine(QImage(VGlobal::icon_path.value("breakpoint")), 2);
}

void VAsmWidget::init_setting()
{
    // skin
    QJsonObject object;
    object = VFunctions::get_file_jsonDocument(VGlobal::skins_dir + "/" + VGlobal::setting.skin_name + "/scintilla.json").object();
    QJsonArray array = object.value("color").toArray();
    foreach(QJsonValue value, array)
    {
        QJsonObject object = value.toObject();
        QString name = object.value("name").toString();

        StyleData style;
        style.fore = object.value("fore").toString().toInt(nullptr, 16);
        style.back = object.value("back").toString().toInt(nullptr, 16);
        style.bold = object.value("fore").toString() == "true";
        style.italic = object.value("italic").toString() == "true";
        _style_map.insert(name, style);
    }
}

void VAsmWidget::init_color()
{
    // lexer 配色
    _lexer.setPaper(_style_map.value("默认").back, -1);
    _lexer.setFont(QFont(VGlobal::setting.textedit_font_name, VGlobal::setting.textedit_font_size));
    _lexer.setColor(_style_map.value("关键字").fore, QsciLexerCPP::Keyword);
    _lexer.setColor(_style_map.value("关键字").fore, QsciLexerCPP::KeywordSet2);
    _lexer.setColor(_style_map.value("双引号块").fore, QsciLexerCPP::DoubleQuotedString);
    _lexer.setColor(_style_map.value("单引号块").fore, QsciLexerCPP::SingleQuotedString);
    _lexer.setColor(_style_map.value("预处理").fore, QsciLexerCPP::PreProcessor);
    _lexer.setColor(_style_map.value("注释块").fore, QsciLexerCPP::Comment);
    _lexer.setColor(_style_map.value("注释行").fore, QsciLexerCPP::CommentLine);
    _lexer.setColor(_style_map.value("标识符").fore, QsciLexerCPP::Identifier);
    _lexer.setColor(_style_map.value("操作符").fore, QsciLexerCPP::Operator);
    _lexer.setColor(_style_map.value("数值").fore, QsciLexerCPP::Number);

    // 行号栏
    this->setMarginsFont(QFont(VGlobal::setting.textedit_font_name, VGlobal::setting.textedit_font_size));
    this->SendScintilla(QsciScintilla::SCI_STYLESETBACK, QsciScintilla::STYLE_LINENUMBER,
                        VFunctions::RGB2BGR(_style_map.value("行号").back));
    this->SendScintilla(QsciScintilla::SCI_STYLESETFORE, QsciScintilla::STYLE_LINENUMBER,
                        VFunctions::RGB2BGR(_style_map.value("行号").fore));

    // 折叠栏
    this->setMarginMarkerMask(QsciScintilla::SC_MARGIN_FORE, QsciScintilla::SC_MASK_FOLDERS);
    this->setFoldMarginColors(_style_map.value("折叠栏").back,
                              _style_map.value("折叠栏").back);

    this->markerDefine(QsciScintilla::MarkerSymbol::BoxedMinus, QsciScintilla::SC_MARKNUM_FOLDEROPEN);
    this->setMarkerForegroundColor(_style_map.value("折叠栏").back, QsciScintilla::SC_MARKNUM_FOLDEROPEN);
    this->setMarkerBackgroundColor(_style_map.value("折叠栏").fore, QsciScintilla::SC_MARKNUM_FOLDEROPEN);

    this->markerDefine(QsciScintilla::MarkerSymbol::BoxedPlus, QsciScintilla::SC_MARKNUM_FOLDER);
    this->setMarkerForegroundColor(_style_map.value("折叠栏").back, QsciScintilla::SC_MARKNUM_FOLDER);
    this->setMarkerBackgroundColor(_style_map.value("折叠栏").fore, QsciScintilla::SC_MARKNUM_FOLDER);

    this->markerDefine(QsciScintilla::MarkerSymbol::VerticalLine, QsciScintilla::SC_MARKNUM_FOLDERSUB);
    this->setMarkerForegroundColor(_style_map.value("折叠栏").back, QsciScintilla::SC_MARKNUM_FOLDERSUB);
    this->setMarkerBackgroundColor(_style_map.value("折叠栏").fore, QsciScintilla::SC_MARKNUM_FOLDERSUB);

    this->markerDefine(QsciScintilla::MarkerSymbol::BottomLeftCorner, QsciScintilla::SC_MARKNUM_FOLDERTAIL);
    this->setMarkerForegroundColor(_style_map.value("折叠栏").back, QsciScintilla::SC_MARKNUM_FOLDERTAIL);
    this->setMarkerBackgroundColor(_style_map.value("折叠栏").fore, QsciScintilla::SC_MARKNUM_FOLDERTAIL);

    this->markerDefine(QsciScintilla::MarkerSymbol::BoxedPlusConnected, QsciScintilla::SC_MARKNUM_FOLDEREND);
    this->setMarkerForegroundColor(_style_map.value("折叠栏").back, QsciScintilla::SC_MARKNUM_FOLDEREND);
    this->setMarkerBackgroundColor(_style_map.value("折叠栏").fore, QsciScintilla::SC_MARKNUM_FOLDEREND);

    this->markerDefine(QsciScintilla::MarkerSymbol::BoxedMinusConnected, QsciScintilla::SC_MARKNUM_FOLDEROPENMID);
    this->setMarkerForegroundColor(_style_map.value("折叠栏").back, QsciScintilla::SC_MARKNUM_FOLDEROPENMID);
    this->setMarkerBackgroundColor(_style_map.value("折叠栏").fore, QsciScintilla::SC_MARKNUM_FOLDEROPENMID);

    this->markerDefine(QsciScintilla::MarkerSymbol::VerticalLine, QsciScintilla::SC_MARKNUM_FOLDERMIDTAIL);
    this->setMarkerForegroundColor(_style_map.value("折叠栏").back, QsciScintilla::SC_MARKNUM_FOLDERMIDTAIL);
    this->setMarkerBackgroundColor(_style_map.value("折叠栏").fore, QsciScintilla::SC_MARKNUM_FOLDERMIDTAIL);

    this->markerDefine(QsciScintilla::MarkerSymbol::BoxedMinus, QsciScintilla::SC_MARKNUM_FOLDEROPEN);
    this->setMarkerForegroundColor(_style_map.value("折叠栏").back, QsciScintilla::SC_MARKNUM_FOLDEROPEN);
    this->setMarkerBackgroundColor(_style_map.value("折叠栏").fore, QsciScintilla::SC_MARKNUM_FOLDEROPEN);

    // 折叠配色
    this->SendScintilla(QsciScintilla::SCI_MARKERSETBACKSELECTED,
        QsciScintilla::SC_MARKNUM_FOLDEROPEN,VFunctions::RGB2BGR(_style_map.value("折叠栏激活状态").fore));
    this->SendScintilla(QsciScintilla::SCI_MARKERSETBACKSELECTED,
        QsciScintilla::SC_MARKNUM_FOLDER, VFunctions::RGB2BGR(_style_map.value("折叠栏激活状态").fore));
    this->SendScintilla(QsciScintilla::SCI_MARKERSETBACKSELECTED,
        QsciScintilla::SC_MARKNUM_FOLDERSUB, VFunctions::RGB2BGR(_style_map.value("折叠栏激活状态").fore));
    this->SendScintilla(QsciScintilla::SCI_MARKERSETBACKSELECTED,
        QsciScintilla::SC_MARKNUM_FOLDERTAIL,VFunctions::RGB2BGR(_style_map.value("折叠栏激活状态").fore));
    this->SendScintilla(QsciScintilla::SCI_MARKERSETBACKSELECTED,
        QsciScintilla::SC_MARKNUM_FOLDEREND, VFunctions::RGB2BGR(_style_map.value("折叠栏激活状态").fore));
    this->SendScintilla(QsciScintilla::SCI_MARKERSETBACKSELECTED,
        QsciScintilla::SC_MARKNUM_FOLDEROPENMID, VFunctions::RGB2BGR(_style_map.value("折叠栏激活状态").fore));
    this->SendScintilla(QsciScintilla::SCI_MARKERSETBACKSELECTED,
        QsciScintilla::SC_MARKNUM_FOLDERMIDTAIL, VFunctions::RGB2BGR(_style_map.value("折叠栏激活状态").fore));

    // 缩进线
    this->setIndentationGuidesForegroundColor(_style_map.value("缩进线").fore);
    this->setIndentationGuidesBackgroundColor(_style_map.value("缩进线").back);

    // 通常背景色
    this->SendScintilla(QsciScintilla::SCI_STYLESETBACK,
        QsciScintilla::STYLE_DEFAULT, VFunctions::RGB2BGR(_style_map.value("默认").back));


    // 插入符号
    this->SendScintilla(QsciScintilla::SCI_SETCARETFORE, VFunctions::RGB2BGR(_style_map.value("插入符号").fore));
    this->SendScintilla(QsciScintilla::SCI_SETCARETLINEBACK,VFunctions::RGB2BGR(_style_map.value("选中行").back));
    qDebug() << "选中行" << _style_map.value("选中行").back;

    // 选择内容样式
    this->setSelectionForegroundColor(_style_map.value("选择文本").fore);
    this->setSelectionBackgroundColor(_style_map.value("选择文本").back);

    // 折叠文本样式
    this->SendScintilla(QsciScintilla::SCI_STYLESETBACK, QsciScintilla::STYLE_FOLDDISPLAYTEXT, VFunctions::RGB2BGR(_style_map.value("折叠文本").back));
    this->SendScintilla(QsciScintilla::SCI_STYLESETFORE, QsciScintilla::STYLE_FOLDDISPLAYTEXT, VFunctions::RGB2BGR(_style_map.value("折叠文本").fore));
    this->SendScintilla(QsciScintilla::SCI_STYLESETFONT, QsciScintilla::STYLE_FOLDDISPLAYTEXT, VGlobal::setting.textedit_font_name.toStdString().data());
    this->SendScintilla(QsciScintilla::SCI_STYLESETSIZE, QsciScintilla::STYLE_FOLDDISPLAYTEXT, VGlobal::setting.textedit_font_size);
}

void VAsmWidget::setText(const QString &text)
{
    VScintillaBase::setText(text);
//    for(int i=0; i<10; i++)
//    {
//        // 前10行分别加入0~2号标记
//        this->SendScintilla(QsciScintilla::SCI_MARKERADD, i, 2);
//    }
//    this->SendScintilla(QsciScintilla::SCI_MARKERADD, 11, 1);
//    this->SendScintilla(QsciScintilla::SCI_MARKERADD, 11, 2);

//	this->markerDefine(QImage(VGlobal::icon_path.value("breakpoint")), 0);
//    this->markerDefine(QImage(VGlobal::icon_path.value("breakpoint")), 1);
//this->markerDefine(QImage(VGlobal::icon_path.value("arror")), 2);

}

void VAsmWidget::set_addr_map(QMap<int, int> map)
{
    _addr_map = map;
}

void VAsmWidget::set_current_addr(int addr)
{
    if(addr == -1 && _pc_line != -1){
        this->SendScintilla(QsciScintilla::SCI_MARKERDELETE, _pc_line, 3);
        _pc_line = -1;
    }

    if(_pc_line != -1){
        this->SendScintilla(QsciScintilla::SCI_MARKERDELETE, _pc_line, 3);
        _pc_line = -1;
    }

    if(_addr_map.contains(addr)){
		_pc_line = _addr_map.value(addr);
		this->setSelect(this->lineStartPos(_pc_line), this->lineStartPos(_pc_line));
        this->SendScintilla(QsciScintilla::SCI_MARKERADD, _pc_line, 3);
    }


}

void VAsmWidget::init_connect()
{
    QObject::connect(this, &VAsmWidget::marginClicked, this, &VAsmWidget::on_marginClicked);
}

void VAsmWidget::init_option()
{
    this->setMarginSensitivity(QsciScintilla::SC_MARGIN_SYMBOL, true);
}

void VAsmWidget::on_marginClicked(int margin, int line)
{
    qDebug() << margin << " line :" << line;
	int marks = this->SendScintilla(QsciScintilla::SCI_MARKERGET, line) / 2;
	if(marks & 2){
		this->SendScintilla(QsciScintilla::SCI_MARKERDELETE, line, 2);
        if(_addr_map.values().contains(line)){
            emit signal_kill_breakpoint(_addr_map.key(line));
        }
	}else{
		this->SendScintilla(QsciScintilla::SCI_MARKERADD, line, 2);
        if(_addr_map.values().contains(line)){
            emit signal_set_breakpoint(_addr_map.key(line));
        }
	}
}








































































